/*
 * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
 * with the License. A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
 * and limitations under the License.
 */
package vfile.face;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point2f;
import org.bytedeco.opencv.opencv_core.Rect;
import org.bytedeco.opencv.opencv_core.Size;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ai.djl.ModelException;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.output.BoundingBox;
import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.output.Landmark;
import ai.djl.modality.cv.output.Point;
import ai.djl.modality.cv.output.Rectangle;
import ai.djl.translate.TranslateException;
import util.ConverterImg;
import util.WorkId;

public final class FeatureDetection {

    private static final Logger logger = LoggerFactory.getLogger(FeatureDetection.class);

    private FeatureDetection() {}

    public static void main(String[] args) throws Exception {
       /* if (!"PyTorch".equals(Engine.getInstance().getEngineName())) {
            logger.info("This example only works for PyTorch.");
            return;
        }*/
    	System.setProperty("ai.djl.default_engine", "PyTorch");
        Path imageFile1 = Paths.get("src/main/resources/img/kana1.jpg"); 
        Mat face = opencv_imgcodecs.imread(imageFile1.toString()/*, opencv_imgcodecs.IMREAD_GRAYSCALE*/);
        Image img1 = ImageFactory.getInstance().fromImage(ConverterImg.m2B(face));//.fromFile(imageFile1); 
        DetectedObjects box1 = RetinaFaceOpencvDetection.predict(img1); 
        
        int imageWidth1 = img1.getWidth();
        int imageHeight1 = img1.getHeight(); 
        
        List<DetectedObjects.DetectedObject> list1 = box1.items();
        List<Mat> faces1 = faces(face,list1,imageWidth1,imageHeight1); 
         
    }

    public static List<Mat> faceDetection(Mat face) throws Exception{ 
         Image img1 = ImageFactory.getInstance().fromImage(ConverterImg.m2B(face));//.fromFile(imageFile1); 
         DetectedObjects box1 = RetinaFaceOpencvDetection.predict(img1);  
         int imageWidth1 = img1.getWidth();
         int imageHeight1 = img1.getHeight(); 
         
         List<DetectedObjects.DetectedObject> list1 = box1.items();
         return  faces(face,list1,imageWidth1,imageHeight1);  
    }
    
    public static List<Mat> faces(Mat src,List<DetectedObjects.DetectedObject> list,int imageWidth1,int imageHeight1) throws IOException{
    	 
    	List<Mat> matFaces = new ArrayList<Mat>();
        for (DetectedObjects.DetectedObject result : list) { 
            BoundingBox box = result.getBoundingBox();
            if (box instanceof Landmark) {
            	Rectangle rectangle = box.getBounds();
                int x = (int) (rectangle.getX() * imageWidth1);
                int y = (int) (rectangle.getY() * imageHeight1); 
                
            	Rect rect = new Rect(x,y,(int) (rectangle.getWidth() * imageWidth1),(int) (rectangle.getHeight() * imageHeight1));
            	
        		Mat rot = new Mat();  
        		if(rect.x() < 0 || rect.y() < 0 ||  rect.y() + rect.height() > src.rows() || rect.x()+rect.width() > src.cols() ){
        			continue;
        		} 
        		 
        		Mat saveFace = new Mat(src, rect);   
        		matFaces.add(saveFace);  
        		//opencv_imgcodecs.imwrite(outputDir.resolve(WorkId.sortUID()+".jpg").toString(),rot);
            } 
        }
        return matFaces;
    } 
}
